package com.andnux.android.utils;

import android.annotation.SuppressLint;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class DateUtils {
    /**
     * 获取时间序号
     *
     * @return 0000000000000xx
     * @Title getRandomNo
     * @Description 当前6位随机数
     */
    public static String getRandomNo() {

        // 获取6位随机数
        String sRandom = Integer.toString((int) (Math.random() * 900000 + 100000));
        if (sRandom.length() > 7) {
            sRandom = sRandom.substring(0, 6);
        } else {
            sRandom = (sRandom + "0").substring(0, 6);
        }

        return System.currentTimeMillis() + sRandom;
    }

    /**
     * 时间格式(yyyy-MM-dd)
     */
    public final static String DATE_PATTERN = "yyyy-MM-dd";

    /**
     * 时间格式(MM月dd)
     */
    public final static String DATE_PATTERN_MM_DD = "MM月dd";

    /**
     * 时间格式(yyyy年MM月dd)
     */
    public final static String DATE_PATTERN_YYYY_MM_DD = "yyyy年MM月dd";

    /**
     * 时间格式(yyyy)
     */
    public final static String DATE_PATTERN_YYYY = "yyyy";

    /**
     * 时间格式(MM)
     */
    public final static String DATE_PATTERN_MM = "MM";

    /**
     * 时间格式(dd)
     */
    public final static String DATE_PATTERN_DD = "dd";

    /**
     * 时间格式(HH:mm)
     */
    public final static String DATE_PATTERN_HH_MM = "HH:mm";

    /**
     * 时间格式(HH时mm分)
     */
    public final static String DATE_PATTERN_HH_MM_2 = "HH时mm分";


    /**
     * 时间格式(yyyyMMdd)
     */
    public final static String DATE_PATTERN_1 = "yyyyMMdd";

    /**
     * 时间格式(yyyyMMddHHmm)
     */
    public final static String DATE_PATTERN_2 = "yyyyMMddHHmm";
    /**
     * 时间格式(yyyy-MM-dd HH:mm:ss)
     */
    public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    public final static String DATE_TIME_PATTERN_SSS = "yyyy-MM-dd HH:mm:ss.SSS";

    public final static String DATE_TIME_PATTERNM = "yyyy-MM-dd HH:mm";
    /**
     * 时间格式(yyyyMMddHHmmssS)
     */
    public final static String DATE_TIME_PATTERN_S = "yyyyMMddHHmmssS";

    /**
     * 时间格式(yyyy-MM-dd HH:mm:ss)
     */
    public final static String DATE_TIME_PATTERN_X = "yyyy-MM-dd_HH:mm:ss";

    /**
     * 日期格式化 日期格式为：yyyy-MM-dd
     *
     * @param date 日期
     * @return 返回yyyy-MM-dd格式日期
     */
    public static String format(Date date) {
        return format(date, DATE_PATTERN);
    }

    /**
     * 日期格式化 日期格式为：yyyy-MM-dd
     *
     * @param date    日期
     * @param pattern 格式，如：DateUtils.DATE_TIME_PATTERN
     * @return 返回yyyy-MM-dd格式日期
     */
    public static String format(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    /**
     * 日期格式化 日期格式为：yyyy-MM-dd
     *
     * @param date 日期
     */
    @SuppressLint("SimpleDateFormat")
    public static String convert(String date, String from, String to) {
        try {
            if (date != null) {
                SimpleDateFormat fromdf = new SimpleDateFormat(from);
                SimpleDateFormat todf = new SimpleDateFormat(to);
                Date parse = fromdf.parse(date);
                if (parse != null) {
                    return todf.format(parse);
                } else {
                    return null;
                }
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 字符串转换成日期
     *
     * @param strDate 日期字符串
     * @param pattern 日期的格式，如：DateUtils.DATE_TIME_PATTERN
     */

    @SuppressLint("SimpleDateFormat")
    public static Date stringToDate(String strDate, String pattern) throws Exception {
        if (StringUtils.isEmpty(strDate)) {
            return null;
        }
        SimpleDateFormat fmt = new SimpleDateFormat(pattern);
        return fmt.parse(strDate);
    }

    /**
     * 根据周数，获取开始日期、结束日期
     *
     * @param week 周期  0本周，-1上周，-2上上周，1下周，2下下周
     * @return 返回date[0]开始日期、date[1]结束日期
     */
    public static Date[] getWeekStartAndEnd(int week) {
        DateTime dateTime = new DateTime();
        LocalDate date = new LocalDate(dateTime.plusWeeks(week));
        date = date.dayOfWeek().withMinimumValue();
        Date beginDate = date.toDate();
        Date endDate = date.plusDays(6).toDate();
        return new Date[]{beginDate, endDate};
    }

    /**
     * 根据周数，获取开始日期、结束日期
     *
     * @param week 周期  0本周，-1上周，-2上上周，1下周，2下下周
     * @return 返回date[0]开始日期、date[1]结束日期
     */
    public static Date[] getWeekStartAndEnd(LocalDate localDate,int week) {
        LocalDate date = new LocalDate(localDate.plusWeeks(week));
        date = date.dayOfWeek().withMinimumValue();
        Date beginDate = date.toDate();
        Date endDate = date.plusDays(6).toDate();
        return new Date[]{beginDate, endDate};
    }

    /**
     * 对日期的【秒】进行加/减
     *
     * @param date    日期
     * @param seconds 秒数，负数为减
     * @return 加/减几秒后的日期
     */
    public static Date addDateSeconds(Date date, int seconds) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusSeconds(seconds).toDate();
    }

    /**
     * 对日期的【分钟】进行加/减
     *
     * @param date    日期
     * @param minutes 分钟数，负数为减
     * @return 加/减几分钟后的日期
     */
    public static Date addDateMinutes(Date date, int minutes) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusMinutes(minutes).toDate();
    }

    /**
     * 对日期的【小时】进行加/减
     *
     * @param date  日期
     * @param hours 小时数，负数为减
     * @return 加/减几小时后的日期
     */
    public static Date addDateHours(Date date, int hours) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusHours(hours).toDate();
    }

    /**
     * 对日期的【天】进行加/减
     *
     * @param date 日期
     * @param days 天数，负数为减
     * @return 加/减几天后的日期
     */
    public static Date addDateDays(Date date, int days) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusDays(days).toDate();
    }

    /**
     * 对日期的【周】进行加/减
     *
     * @param date  日期
     * @param weeks 周数，负数为减
     * @return 加/减几周后的日期
     */
    public static Date addDateWeeks(Date date, int weeks) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusWeeks(weeks).toDate();
    }

    /**
     * 对日期的【月】进行加/减
     *
     * @param date   日期
     * @param months 月数，负数为减
     * @return 加/减几月后的日期
     */
    public static Date addDateMonths(Date date, int months) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusMonths(months).toDate();
    }

    /**
     * 对日期的【年】进行加/减
     *
     * @param date  日期
     * @param years 年数，负数为减
     * @return 加/减几年后的日期
     */
    public static Date addDateYears(Date date, int years) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusYears(years).toDate();
    }

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd） pattern可以为：DateUtils.DATE_PATTERN "HH:mm:ss" "E"
     */
    public static String getDate(String pattern) {
        return new SimpleDateFormat(pattern, Locale.CANADA).format(DateUtils.date());
    }

    /**
     * 得到当前年份字符串 格式（yyyy）
     */
    public static String getYear() {
        return new SimpleDateFormat("yyyy", Locale.CANADA).format(DateUtils.date());
    }


    /**
     * 日期相差的天数
     */
    public static int diff(Date start, Date end) throws Exception {
        int days = (int) ((end.getTime() - start.getTime()) / (1000 * 3600 * 24));
        if (days >= 0) {
            return days;
        } else {
            throw new Exception("日期参数传递错误，结束日期应大于或等于开始日期");
        }
    }

    public static int diffHour(Date start, Date end) throws Exception {
        int days = (int) ((end.getTime() - start.getTime()) / (1000 * 3600));
        if (days >= 0) {
            return days;
        } else {
            throw new Exception("日期参数传递错误，结束日期应大于或等于开始日期");
        }
    }


    //      todo xjz 2020-6-17

    /**
     * 获取今天
     *
     * @return String
     */
    public static String getToday() {
        return new SimpleDateFormat(DateUtils.DATE_PATTERN, Locale.CANADA).format(DateUtils.date());
    }

    /**
     * 获取今天
     *
     * @return String
     */
    public static String getTodayString(String pattern) {
        SimpleDateFormat sqf = new SimpleDateFormat(pattern, Locale.CANADA);
        return sqf.format(DateUtils.date());
    }

    /**
     * 获取今天
     *
     * @return String
     */
    public static Date getToday(String pattern) throws Exception {
        SimpleDateFormat sqf = new SimpleDateFormat(pattern, Locale.CANADA);
        String sq = sqf.format(DateUtils.date());
        Date date = DateUtils.stringToDate(sq, pattern);
        return date;
    }

    /**
     * 获取昨天
     *
     * @return String
     */
    public static String getYestoday() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1);
        Date time = cal.getTime();
        return new SimpleDateFormat(DateUtils.DATE_PATTERN, Locale.CANADA).format(time);
    }

    /**
     * 获取本月开始日期
     *
     * @return String
     **/
    public static String getMonthStart() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, 0);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date time = cal.getTime();
        return new SimpleDateFormat(DateUtils.DATE_PATTERN, Locale.CANADA).format(time) + " 00:00:00";
    }

    /**
     * 获取本月最后一天
     *
     * @return String
     **/
    public static String getMonthEnd() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date time = cal.getTime();
        return new SimpleDateFormat(DateUtils.DATE_PATTERN, Locale.CANADA).format(time) + " 23:59:59";
    }

    /**
     * 获取本周的第一天
     *
     * @return String
     **/
    public static String getWeekStart() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.WEEK_OF_MONTH, 0);
        cal.set(Calendar.DAY_OF_WEEK, 2);
        Date time = cal.getTime();
        return new SimpleDateFormat(DateUtils.DATE_PATTERN, Locale.CANADA).format(time) + " 00:00:00";
    }

    /**
     * 获取本周的最后一天
     *
     * @return String
     **/
    public static String getWeekEnd() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_WEEK, cal.getActualMaximum(Calendar.DAY_OF_WEEK));
        cal.add(Calendar.DAY_OF_WEEK, 1);
        Date time = cal.getTime();
        return new SimpleDateFormat(DateUtils.DATE_PATTERN, Locale.CANADA).format(time) + " 23:59:59";
    }

    /**
     * 获取本年的第一天
     *
     * @return String
     **/
    public static String getYearStart() {
        return new SimpleDateFormat("yyyy", Locale.CANADA).format(DateUtils.date()) + "-01-01" + " 00:00:00";
    }

    /**
     * 获取本年的最后一天
     *
     * @return String
     **/
    public static String getYearEnd() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, calendar.getActualMaximum(Calendar.MONTH));
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date currYearLast = calendar.getTime();
        return new SimpleDateFormat(DateUtils.DATE_PATTERN, Locale.CANADA).format(currYearLast) + " 23:59:59";
    }

    public static Date getYearEnd2() throws Exception {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, calendar.getActualMaximum(Calendar.MONTH));
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date currYearLast = calendar.getTime();
        return DateUtils.stringToDate(new SimpleDateFormat(DateUtils.DATE_PATTERN, Locale.CANADA).format(currYearLast), DateUtils.DATE_PATTERN);
    }

    /**
     * 获取明年的第一天
     *
     * @return String
     **/
    public static String getYearMStart() {
        return new SimpleDateFormat("yyyy", Locale.CANADA).format(addDateYears(DateUtils.date(), 1)) + "-01-01" + " 00:00:00";
    }

    /**
     * 获取明年的最后一天
     *
     * @return String
     **/
    public static String getYearMEnd() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, calendar.getActualMaximum(Calendar.MONTH));
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date currYearLast = calendar.getTime();
        return new SimpleDateFormat(DateUtils.DATE_PATTERN, Locale.CANADA).format(addDateYears(currYearLast, 1)) + " 23:59:59";
    }

    /**
     * 年度第一周的星期一这年度的第几天
     *
     * @param year
     * @return
     */
    public static int getFirstWeekDayNum(int year) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return Integer.parseInt(String.format("%tj", cal.getTime()));
    }

    /**
     * 日期时星期几
     *
     * @param date
     * @return
     */
    public static int getWeekOfDate(Date date) {
        int[] weekdays = {6, 0, 1, 2, 3, 4, 5};
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0) {
            w = 0;
        }
        return weekdays[w];
    }


    /**
     * 日期时星期几
     *
     * @param date
     * @return
     */
    public static int getWeekOfDateMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.WEEK_OF_MONTH);
        return w;
    }

    /**
     * 当前时间是本年的第几周
     *
     * @param date
     * @return
     */
    public static int getWeekOfYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.WEEK_OF_YEAR);
        return w;
    }

    /**
     * 获取上个月最后一天
     *
     * @param
     * @return
     */
    public static Date lastDateOfPrevMonth() throws Exception {
        Date date = DateUtils.getToday(DATE_PATTERN);
        Calendar c = Calendar.getInstance();
        //设置指定日期；
        c.setTime(date);
        c.add(Calendar.MONTH, -1);
        c.set(Calendar.DATE, c.getActualMaximum(Calendar.DATE));
        Date lastDateOfPrevMonth = c.getTime();
        return lastDateOfPrevMonth;
    }

    public static String firstDayOfThisWeek() {
        Calendar curStartCal = Calendar.getInstance();
        Calendar cal = (Calendar) curStartCal.clone();
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        String firstDate = DateUtils.format(cal.getTime(), DATE_PATTERN);
        return firstDate;
    }

    public static String lastDayOfThisWeek() {
        Calendar curStartCal = Calendar.getInstance();
        Calendar cal = (Calendar) curStartCal.clone();
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        cal.add(Calendar.DATE, 6);
        String lastDate = DateUtils.format(cal.getTime(), DATE_PATTERN);
        return lastDate;
    }

    public static int getDayNum(Date startTime, Date endTime) throws Exception {
        Date start = DateUtils.stringToDate(DateUtils.format(startTime, DATE_PATTERN), DATE_PATTERN);
        Date end = DateUtils.stringToDate(DateUtils.format(endTime, DATE_PATTERN), DATE_PATTERN);
        if (start == end) {
            return 0;
        }
        int num = 0;
        for (; addDateDays(start, num).getTime() != end.getTime(); ) {
            num++;
        }
        return num;
    }

    /**
     * 根据日期获取周几
     *
     * @param date
     * @return
     */
    public static String getWeekByDay(Date date) {
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        try {
            cal.setTime(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0) {
            w = 0;
        }
        return weekDays[w];
    }

    public static String getDateString(long time, String format) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(new Date(time));
    }

    //当天时间戳
    public static Long[] getTodayRange() {
        Long[] range = new Long[2];
        Calendar c = Calendar.getInstance();
        c.set(Calendar.HOUR, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MINUTE, 0);
        range[0] = c.getTimeInMillis();

        c.set(Calendar.HOUR, 23);
        c.set(Calendar.SECOND, 59);
        c.set(Calendar.MINUTE, 59);
        range[1] = c.getTimeInMillis();
        return range;
    }

    //明天时间戳
    public static Long[] getTomorrowRange() {
        Long[] range = new Long[2];
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, 1);
        c.set(Calendar.HOUR, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.MILLISECOND, 0);
        range[0] = c.getTimeInMillis();

        c.set(Calendar.HOUR, 23);
        c.set(Calendar.SECOND, 59);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.MILLISECOND, 998);
        range[1] = c.getTimeInMillis();
        return range;
    }

    //获取本周时间戳
    public static Long[] getWeekRange() {
        Long[] range = new Long[2];
        Calendar c = Calendar.getInstance();
        c.set(Calendar.DAY_OF_WEEK, 1);
        c.set(Calendar.HOUR, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.MILLISECOND, 0);
        range[0] = c.getTimeInMillis();

        c.set(Calendar.DAY_OF_WEEK, 7);
        c.set(Calendar.HOUR, 23);
        c.set(Calendar.SECOND, 59);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.MILLISECOND, 998);
        range[1] = c.getTimeInMillis();

        return range;
    }

    /**
     * 获取当前时间
     *
     * @return 当前时间
     */
    public static Date date() {
        return new Date();
    }
}
